/*
        Author: Katherine Cruse
        File Name: date.c
        Description: Displays or sets the date
        Last updated: 9/12/11 (Nathan)

*/

#include "mpx_supt.h"
#include "commhand.h"
#include "date.h"
	
//primary method to get or set the date	
int getDate(char args[MAX_NARGS][MAX_ARGLEN], int nargs){
	date_rec targetDate; //the target date

	//no arguments, do nothing
	if(nargs==0) return 0;
	
	//DATE command: display current system date
	if(strcmp(args[0],"DATE")==0){
		if(nargs>1) printf("Error: Improper command DATE syntax\nUsage: DATE <no arguments>\n");
		else {
			sys_get_date(&targetDate);//display date
			displayDate(targetDate);
		}
		return 1;
	}
	
	//CHDATE command: change system date
	if(strcmp(args[0],"CHDATE")==0){
		if(nargs!=4||strlen(args[1])!=2||strlen(args[2])!=2||strlen(args[3])!=4) {
			printf("Error: Improper command CHDATE syntax\nUsage: CHDATE mm dd yyyy\n'mm' is the two-digit month,\n'dd' is the two-digit day,\n'yyyy' is the four-digit year\n");
			return 1;
		}
		if(checkMonth(args[1],&targetDate)==0){
			printf("Error: Unable to parse month %s for command CHDATE\nMonths must be two digits\n",args[1]);
			return 1;
		}	
		if(checkYear(args[3],&targetDate)==0){
			printf("Error: Unable to parse year %s for command CHDATE\nMonths must be two digits\n",args[3]);
			return 1;
		}
		if(checkDay(args[2],&targetDate)==0){
			printf("Error: Invalid day %s for command CHDATE with given month %s and year %s\n",args[2],args[1],args[3]);
			return 1;
		} 
		if(sys_set_date(&targetDate)==0) {
			printf("Date successfully changed!\n");
			displayDate(targetDate);
		}
		else printf("Error: unable to set the system date.  Please consult an administrator.\n");
		return 1;
	} 
	//first argument does not match this command
	return 0; 
}


		
		
//check and set month date	
int checkMonth(char *argPtr, date_rec *drPtr){
	int mon = parsePosInt(argPtr);
	if(mon > 0 && mon < 13) {
		(*drPtr).month = mon;
		return 1;
	}
	return 0;
}

//Check that the day is valid with the current month and year in the date_rec object; if so, sets the value
int checkDay(char *arg, date_rec *drPtr){
	int day=parsePosInt(arg), mon=(*drPtr).month, yr = (*drPtr).year;
	//check valid day for month and year in *drPtr
	if(day<=0) return 0;
	//checks for valid amount of days in Jan, March, May, July, Aug, Oct, Dec
	if(mon==1||mon==3||mon==5||mon==7||mon==8||mon==10||mon==12){
		if(day<=31){
			(*drPtr).day=day;
			return 1;
		}
	}
	//checks for valid amount of days in Sep, April, June, Nov
	if(mon==4||mon==6||mon==9||mon==11){
		if(day<=30){
			(*drPtr).day=day;
			return 1;
		}
	}
	//checks for valid amount of days in Feb
	if(mon==2){
		if(day<=28){
			(*drPtr).day=day;
			return 1;
		}
		//consider leap years
		else if(day==29){
			if(checkForLeapYear(yr)==1){
				(*drPtr).day=day;
				return 1;
			}
		}
	}		
	return 0;
}

//checks for a valid year and if so inserts the value in the date_rec object
int checkYear(char *arg, date_rec *drPtr){
	int yr=parsePosInt(arg);
	if(yr<0) return 0;
	(*drPtr).year = yr;
	return 1;	
}

//Checks whether the given year is a leap year
int checkForLeapYear(int year){
	if(year%4!=0)return 0;
	if(year%100!=0 || year%400==0)return 1;
	return 0;	
}

//Display the date data
void displayDate(date_rec date){
	char mon[15];
	switch (date.month){
		case (1): strcpy(mon,"January"); break;
		case (2): strcpy(mon,"February"); break;
		case (3): strcpy(mon,"March"); break;
		case (4): strcpy(mon,"April"); break;
		case (5): strcpy(mon,"May"); break;
		case (6): strcpy(mon,"June"); break;
		case (7): strcpy(mon,"July"); break;
		case (8): strcpy(mon,"August"); break;
		case (9): strcpy(mon,"September"); break;
		case (10): strcpy(mon,"October"); break;
		case (11): strcpy(mon,"November"); break;
		case (12): strcpy(mon,"December"); break;
		default: printf("The date is now!\n"); return;
	}
	printf("The current date is %s %d, %d\n", mon, date.day, date.year);
}		

//Parse an argument as a positive integer, return 1 if fail
int parsePosInt(char *arg){
	int tenPowMax = strlen(arg)-1, total=0, tenPow,test;
	if(tenPowMax<0) return -1;
	for(tenPow = 0; tenPow <= tenPowMax; tenPow++){
		test = arg[tenPowMax-tenPow]-48;
		if(test<0 || test>9) {
			return -1;
		}	
		total += pow(10,tenPow)*test;
	}
	return total;
}
//Convenient power method for integers
int pow(int base, int exp){
	int i, total=1;
	for(i=0;i<exp;i++){
		total *= base;
	}
	return total;
}